package com.train.mgr.modules.biz.utils;

import com.train.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class Mp4ToImageList {


    /**
     * 每 5 秒抽一帧，不足 5 秒直接结束
     * @param mp4      输入文件
     * @param mp4Url   原路径（用于取目录）
     * @param duration 视频总时长（秒）
     * @param format   图片格式 jpg/png
     * @return 生成图片的绝对路径列表（按时间顺序）
     */
    public static List<String> mp4ConvertImages(File mp4, String mp4Url,
                                                double duration,
                                                String format) {
        long t = System.currentTimeMillis();
        try {
            String mp4FileDir = Paths.get(mp4Url).getParent().toString();
            File outDir = new File(mp4FileDir);
            String dateMs = DateUtils.dateTimeNowMs() + "_";
            if (!outDir.exists()) outDir.mkdirs();

            List<String> result = new ArrayList<>();
            double timestamp = 0.0;          // 从 0 秒开始
            int index = 1;                   // 帧序号从 1 开始
            while (timestamp < duration) {
                String fileName = String.format("%s%03d.%s", dateMs, index++, format);
                File target = new File(outDir, fileName);

                String[] cmd = {
                        "ffmpeg", "-y",
                        "-ss", String.format("%.3f", timestamp),
                        "-i", mp4.getAbsolutePath(),
                        "-vframes", "1",
                        "-q:v", "2",
                        target.getAbsolutePath()
                };

                ProcessBuilder pb = new ProcessBuilder(cmd);
                pb.redirectErrorStream(true);
                Process p = pb.start();
                try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
                    while (br.readLine() != null) { /* 静默 */ }
                }
                int exit = p.waitFor();
                if (exit == 0 && target.length() > 0) {
                    result.add(target.getAbsolutePath());
                } else {
                    log.error("抽帧失败 timestamp={}s, exit={}, fileLen={}",
                            timestamp, exit, target.length());
                    if (target.exists()) target.delete();
                }

                // 步进 5 秒
                timestamp += 5.0;
            }

            log.info("抽帧完成，共 {} 张 → {}", result.size(), outDir.getAbsolutePath());
            return result;
        } catch (IOException | InterruptedException e) {
            log.error("抽帧异常", e);
            Thread.currentThread().interrupt();
            return null;
        } finally {
            long cost = (System.currentTimeMillis() - t) / 1_000;
            log.info("从MP4抽帧总耗时: {} s", cost);
        }
    }

    /**
     * 均匀抽帧并返回图片文件列表
     * @param mp4      输入文件
     * @param count    需要抽取的帧数
     * @param format   图片格式 jpg/png
     * @return         生成图片的 File 列表（按时间顺序）
     */
    public static List<String> mp4ConvertImagesOld(File mp4,String mp4Url,double duration, int count,String format) {
        //log.info("mp4ConvertImages mp4Url:{}",mp4Url);
        long t = System.currentTimeMillis();
        try{
            String mp4FileDir = Paths.get(mp4Url).getParent().toString();
            File outDir = new File(mp4FileDir);
            String dateMs = DateUtils.dateTimeNowMs()+"_";
            if (!outDir.exists()) outDir.mkdirs();
            BigDecimal step = BigDecimal.valueOf(duration)
                    .divide(BigDecimal.valueOf(count), 4, RoundingMode.HALF_UP);

            List<String> result = new ArrayList<>(count);   // ← 改这里
            for (int i = 0; i < count; i++) {
               // double timestamp = step.multiply(BigDecimal.valueOf(i + 0.5)).doubleValue();
                double timestamp = Math.min(
                        step.multiply(BigDecimal.valueOf(i + 0.5)).doubleValue(),
                        duration - 0.001);   // 至少留 1ms 余量
                String fileName = String.format("%s%03d.%s", dateMs, i + 1, format);
                File target = new File(outDir, fileName);

                String[] cmd = {
                        "ffmpeg", "-y",
                        "-ss", String.format("%.3f", timestamp),
                        "-i", mp4.getAbsolutePath(),
                        "-vframes", "1",
                        "-q:v", "2",
                        target.getAbsolutePath()
                };

                ProcessBuilder pb = new ProcessBuilder(cmd);
                pb.redirectErrorStream(true);
                Process p = pb.start();
                try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
                    while (br.readLine() != null) { /* 静默 */ }
                }
                int exit;
                try {
                    exit = p.waitFor();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    exit = -1;
                }
                if (exit == 0 && target.length() > 0) {
                    result.add(target.getAbsolutePath()); // ← 直接存字符串
                } else {
                    log.error("抽帧失败或生成空文件，timestamp={}s, exit={}, fileLen={}",
                            timestamp, exit, target.length());
                    if (target.exists()) target.delete();   // 清理残文件

                    /* 可选：最后一张失败直接结束循环，避免继续 */
                    if (i == count - 1) {
                        log.warn("最后一张抽帧失败，终止后续处理");
                        break;
                    }
                }
            }
            log.info("抽帧完成，共 " + result.size() + " 张 → " + outDir.getAbsolutePath());
           // log.info("result LIST:{}", JSONObject.toJSONString(result));
            return result;   // ← 返回列表
        }catch (IOException ex){
            log.error("error",ex);
            ex.printStackTrace();
            return null;
        }finally {
            long cost = (System.currentTimeMillis() - t ) / 1_000;
            log.info(" 从MP4抽帧总耗时: " + cost + " s");
        }

    }

//
//    /* ---------------- 测试 ---------------- */
//    public static void main(String[] args) throws IOException {
//        File mp4    = new File("/Users/tianyi/Documents/logo/aaaa.mp4");
//        int  count  =  10;
//        String format =  "jpg";
//
//        extract(mp4,"/Users/tianyi/Documents/logo/aaaa.mp4",300, count, format);
//    }
}
